package com.cxx.autoconfigure.web;

import cn.dev33.satoken.exception.SaTokenException;
import com.cxx.autoconfigure.util.WebUtils;
import com.cxx.framework.web.AbstractException;
import com.cxx.framework.web.ErrorResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class DefaultExceptionAdvice {

    private static final Logger logger = LoggerFactory.getLogger(DefaultExceptionAdvice.class);

    /**
     * 处理SaToken权限错误
     * @param e 权限异常
     * @return 错误响应
     */
    @ExceptionHandler(SaTokenException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ErrorResponse handleSaTokenException(SaTokenException e) {
        ErrorResponse response = new ErrorResponse(String.valueOf(e.getCode()), e.getMessage());
        logger.error("<{}> {}", response.getCode(), e.toString());
        return response;
    }

    /**
     * 处理参数校验错误
     * @param e 校验异常
     * @return 错误响应
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ErrorResponse handleValidationException(MethodArgumentNotValidException e) {
        ErrorResponse response = new ErrorResponse(WebUtils.formatValidationException(e.getBindingResult().getFieldErrors()));
        logger.error("<{}> {}", response.getCode(), response.getMessage());
        return response;
    }

    /**
     * 处理自定义异常错误
     * @param e 自定义异常
     * @return 错误响应
     */
    @ExceptionHandler(AbstractException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResponse handleAbstractException(AbstractException e) {
        ErrorResponse response;
        if (e.getCode() == null || e.getCode().isEmpty()) {
            response = new ErrorResponse(e.getMessage());
        } else {
            response = new ErrorResponse(e.getCode(), e.getMessage());
        }
        logger.error(String.format("<%s> ", response.getCode()), e);
        return response;
    }

    /**
     * 处理默认异常错误
     * @param e 默认异常
     * @return 错误响应
     */
    @ExceptionHandler
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResponse handleDefaultException(Exception e) {
        ErrorResponse response = new ErrorResponse(e.getMessage());
        logger.error(String.format("<%s> ", response.getCode()), e);
        return response;
    }
}
